home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / tool / extdrv / src / buf_rdir.c < prev    next >
C/C++ Source or Header  |  1994-11-16  |  4KB  |  170 lines

  1. #include "extdrv.h"
  2. #include "file.h"
  3. #include "dir.h"
  4. #include "buffer.h"
  5. #include "dos.h"
  6. #include "extern.h"
  7.  
  8. int n_rootdir;
  9. struct rdirbuf far *root_base = NULL, far *root_dir = NULL;
  10. struct rdirbuf far *root_tail = NULL;
  11.  
  12. struct rdirbuf far *get_root(struct drvinfo far *d, u_int entry)
  13. {
  14.     u_short off, sector;
  15.     struct rdirbuf far *p, far *free;
  16.  
  17.     off = entry / N_RDIR_ENTRY;
  18.     free = NULL;
  19.     for (p = root_dir; p != NULL; p = p->next){
  20.         if (p->drv == d  &&  p->off == off){
  21.             if (p != root_dir){
  22.                 if ((p->prev->next = p->next) == NULL)
  23.                     root_tail = p->prev;
  24.                 else
  25.                     p->next->prev = p->prev;
  26.                 p->next = root_dir;
  27.                 p->prev = NULL;
  28.                 root_dir->prev = p;
  29.                 root_dir = p;
  30.             }
  31.             return (p);
  32.         }
  33.         if (p->drv == NULL)
  34.             free = p;
  35.     }
  36.     if (free == NULL){
  37.         p = root_tail;
  38.         if (p->pp != NULL){
  39.             p->pp->drv = NULL; /* invalidate */
  40.             p->pp = NULL;
  41.         }
  42.         if (p->dirty){
  43.             d = p->drv;
  44.             sector = RDIRBUFSIZ / d->sectsiz;
  45.             sector = d->rdir_off + p->off * sector;
  46.             if (write2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, p->buf) != 0){
  47. #ifdef DEBUG
  48.                 auxputs("write error ");
  49. #endif
  50.                 return (NULL);
  51.             }
  52.             p->dirty = FALSE;
  53.         }
  54.         root_tail = p->prev;
  55.         p->prev->next = NULL;
  56.         root_dir->prev = p;
  57.         p->next = root_dir;
  58.         p->prev = NULL;
  59.         root_dir = p;
  60.     } else {
  61.         if ((p = free) != root_dir){
  62.             if (p->next == NULL)
  63.                 root_tail = p->prev;
  64.             else
  65.                 p->next->prev = p->prev;
  66.             p->prev->next = p->next;
  67.             root_dir->prev = p;
  68.             p->next = root_dir;
  69.             p->prev = NULL;
  70.             root_dir = p;
  71.         }
  72.     }
  73.     p->drv = d;
  74.     p->off = off;
  75.     if (off == d->rdir_last_sec)
  76.         p->n_entry = d->rdir_last_size;
  77.     else
  78.         p->n_entry = N_RDIR_ENTRY;
  79.  
  80.     sector = RDIRBUFSIZ / d->sectsiz;
  81.     sector = d->rdir_off + off * sector;
  82.     if (read2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, p->buf) != 0){
  83. #ifdef DEBUG
  84.         auxputs("read error ");
  85. #endif
  86.         p->drv = NULL;
  87.         return (NULL);
  88.     }
  89. #ifdef DEBUG_BUF
  90.     auxputs("RBUF#");
  91.     auxprinthex((u_long)((char far *)p - (char far *)root_base)/sizeof (struct rdirbuf));
  92.     auxputs(" DISK-READ,");
  93.     auxprinthex(sector);
  94.     auxputs(",");
  95.     auxprinthex(p->n_entry);
  96.     auxputs(" ");
  97. #endif
  98.     return (p);
  99. }
  100.  
  101. flush_root(struct drvinfo far *d, int invalidate)
  102. {
  103.     struct rdirbuf far *p;
  104.     u_short sector;
  105.     
  106. #ifdef DEBUG
  107.     auxputs("flush_root ");
  108. #endif
  109.         for (p = root_dir; p != NULL; p = p->next){
  110.         if ((d == NULL && p->drv != NULL) || p->drv == d){
  111.             if (p->dirty){
  112.                 d = p->drv;
  113.                 sector = RDIRBUFSIZ / d->sectsiz;
  114.                 sector = d->rdir_off + p->off * sector;
  115.                 if (write2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, 
  116.                             p->buf) != 0){
  117. #ifdef DEBUG
  118.                     auxputs("write error ");
  119. #endif
  120.                     return (-1);
  121.                 }
  122.                 p->dirty = FALSE;
  123.             }
  124.             if (invalidate){
  125.                 if (p->pp != NULL){
  126.                     p->pp->drv = NULL; /* invalidate */
  127.                     p->pp = NULL;
  128.                 }
  129.                 p->drv = NULL;
  130.             }
  131.         }
  132.     }
  133.     return (0);
  134. }
  135.  
  136. inv_root(u_int devno)
  137. {
  138.     struct rdirbuf far *p;
  139.  
  140.     for (p = root_dir; p != NULL; p = p->next){
  141.         if (p->drv != NULL  &&  p->drv->devno == devno){
  142.             if (p->pp != NULL){
  143.                 p->pp->drv = NULL;
  144.                 p->pp = NULL;
  145.             }
  146.             p->drv = NULL;
  147.             p->dirty = FALSE;
  148.         }
  149.     }
  150.     return (0);
  151. }
  152.  
  153. struct rdirbuf far *root_read(struct drvinfo far *d, int entry)
  154. {
  155.     struct rdirbuf far *p;
  156.  
  157.     if (entry >= d->n_rdir)
  158.         return (NULL);
  159.     if ((p = get_root(d, entry)) == NULL){
  160.         return (NULL);
  161.     }
  162. #ifdef DEBUG_BUF
  163.     auxputs("RBUF#");
  164.     auxprinthex((u_long)((char far *)p - (char far *)root_base)/sizeof (struct rdirbuf));
  165.     auxputs(" ");
  166.     auxputs("\r\n");
  167. #endif
  168.     return (p);
  169. }
  170.